﻿using SqlSugar;
using StoreSQLSugar.DBUtility;
using StoreSQLSugar.Forms.StoreFrm;
using StoreSQLSugar.Helpers;
using StoreSQLSugar.Models;
using StoreSQLSugar.Models.ViewModel;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace StoreSQLSugar.Forms
{
    // T指实体类，K指视图实体类，M指添加或编辑窗体
    // 语法：先继承基类，再给泛型添加约束。
    public partial class BaseListFrm<T, K, M> : UserControl
        where T : Base
        where K : VBase, new()
        where M : Form
    {
        #region 子窗体可以调用的代码
        // 动态创建文本查询控件
        public TextBox TxtCondition { get; set; }

        public BaseListFrm()
        {
            InitializeComponent();

            // 手动绑定相关控件事件
            cbbSearchCondition.SelectedIndexChanged += cbbSearchCondition_SelectedIndexChanged;
            btnSearch.Click += btnSearch_Click;
            btnAdd.Click += btnAdd_Click;
            btnUpdate.Click += btnUpdate_Click;
            btnDelete.Click += btnDelete_Click;
            btnEnabled.Click += btnEnabled_Click;
            dataGridView1.CellFormatting += dataGridView1_CellFormatting;
            ucPager1.PageChanged += UcPager1_PageChanged;
        }

        // 构建查询表达式
        public Expressionable<K> BuildCondition()
        {
            var exp = Expressionable.Create<K>();

            if (cbbSearchCondition.SelectedItem.ToString() == "创建时间")
            {
                DateTime start = DateTime.Parse(dtStartTime.Value.ToString("yyyy-MM-dd") + " 00:00:00");
                DateTime end = DateTime.Parse(dtStartTime.Value.ToString("yyyy-MM-dd") + " 23:59:59");
                exp.Or(ut => ut.CreateTime >= start && ut.CreateTime <= end);
            }
            else if (cbbSearchCondition.SelectedItem.ToString() == "修改时间")
            {
                DateTime start = DateTime.Parse(dtStartTime.Value.ToString("yyyy-MM-dd") + " 00:00:00");
                DateTime end = DateTime.Parse(dtStartTime.Value.ToString("yyyy-MM-dd") + " 23:59:59");
                exp.Or(ut => ut.LastUpdateTime >= start && ut.LastUpdateTime <= end);
            }
            else
            {
                exp.OrIF(!string.IsNullOrWhiteSpace(TxtCondition.Text), ut =>
                ut.Remark.Contains(TxtCondition.Text) ||
                ut.StatusName.Contains(TxtCondition.Text) ||
                ut.CreateUserName.Contains(TxtCondition.Text) ||
                ut.LastUpdateUserName.Contains(TxtCondition.Text)
                );
            }

            return exp;
        }

        // 查询数据，排序，分页，取总页数，绑定网格等
        public void Search(Expressionable<K> exp, string order)
        {
            var query = SqlSugarHelper.Db.Queryable<K>().Where(exp.ToExpression()).OrderBy(order);
            int count = query.Count();
            ucPager1.TotalPage = count % ucPager1.PageSize == 0 ? count / ucPager1.PageSize : count / ucPager1.PageSize + 1;

            dataGridView1.DataSource = query.Skip((ucPager1.Page - 1) * ucPager1.PageSize).Take(ucPager1.PageSize)
                .ToList();
        }

        // 设置列标题，是否显示，格式化等
        public void SetColumn(List<dynamic> headerColumns, List<dynamic> hiddenColumns, List<dynamic> formatColumns)
        {
            headerColumns.AddRange(new List<dynamic>() {
                new { Name="Remark", HeaderText="备注"},
                new { Name="Status", HeaderText="状态"},
                new { Name="StatusName", HeaderText="状态"},
                new { Name="CreateUserId", HeaderText="创建人"},
                new { Name="CreateUserName", HeaderText="创建人"},
                new { Name="CreateTime", HeaderText="创建时间"},
                new { Name="LastUpdateUserId", HeaderText="修改人"},
                new { Name="LastUpdateUserName", HeaderText="修改人"},
                new { Name="LastUpdateTime", HeaderText="修改时间"}
            });
            foreach (var column in headerColumns)
            {
                dataGridView1.Columns[column.Name].HeaderText = column.HeaderText;
            }

            hiddenColumns.AddRange(new List<dynamic>() {
                new { Name="Status", Visible=false},
                new { Name="CreateUserId", Visible=false},
                new { Name="LastUpdateUserId", Visible=false}
            });
            foreach (var column in hiddenColumns)
            {
                dataGridView1.Columns[column.Name].Visible = column.Visible;
            }

            formatColumns.AddRange(new List<dynamic>() {
                new { Name="CreateTime", Format="yyyy-MM-dd HH:mm:ss"},
                new { Name="LastUpdateTime", Format="yyyy-MM-dd HH:mm:ss"},
            });
            foreach (var column in formatColumns)
            {
                dataGridView1.Columns[column.Name].DefaultCellStyle.Format = column.Format;
            }
        }
        #endregion

        #region 子窗体不能调用的代码
        // 动态创建日期查询控件
        private DateTimePicker dtStartTime = null;
        private DateTimePicker dtEndTime = null;

        // 下拉框架中查询条件变化时执行逻辑
        private void cbbSearchCondition_SelectedIndexChanged(object sender, EventArgs e)
        {
            ComboBox comboBox = sender as ComboBox;
            if (comboBox.SelectedItem.ToString().Contains("时间"))
            {
                panelSearchCondition.Controls.Clear();
                TxtCondition = null;

                dtStartTime = new DateTimePicker();
                int y = (panelSearchCondition.Height - dtStartTime.Height) / 2;
                dtStartTime.Location = new Point(0, y);
                panelSearchCondition.Controls.Add(dtStartTime);

                dtEndTime = new DateTimePicker();
                dtEndTime.Location = new Point(dtStartTime.Width + 10, y);
                panelSearchCondition.Controls.Add(dtEndTime);
            }
            else
            {
                panelSearchCondition.Controls.Clear();
                dtStartTime = null;
                dtEndTime = null;

                TxtCondition = new TextBox();
                int y = (panelSearchCondition.Height - TxtCondition.Height) / 2;
                TxtCondition.Width = panelSearchCondition.Width - 20;
                TxtCondition.Location = new Point(0, y);
                panelSearchCondition.Controls.Add(TxtCondition);
            }
        }

        // 查询按钮逻辑
        private void btnSearch_Click(object sender, EventArgs e)
        {
            ucPager1.Page = 1;
        }

        // 设置窗体默认按钮
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.Enter)
            {
                btnSearch.PerformClick();
                return true; // 表示消息已被处理
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }

        // 打开添加窗体
        private void btnAdd_Click(object sender, EventArgs e)
        {
            var frm = Activator.CreateInstance(typeof(M), 0) as M;
            if (frm.ShowDialog() == DialogResult.OK)
            {
                btnSearch.PerformClick();
            }
        }

        // 打开修改窗体
        private void btnUpdate_Click(object sender, EventArgs e)
        {
            if (dataGridView1.SelectedRows.Count != 1)
            {
                MessageBox.Show("请选择一条数据进行修改！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            int id = int.Parse(dataGridView1.SelectedRows[0].Cells[0].Value.ToString());
            var model = SqlSugarHelper.Db.Queryable<T>().InSingle(id);
            if (model != null && model.Status == 1)
            {
                MessageBox.Show("不能修改已删除的数据！请先启用数据！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            var frm = Activator.CreateInstance(typeof(M), id) as M;
            if (frm.ShowDialog() == DialogResult.OK)
            {
                btnSearch.PerformClick();
            }
        }

        // 删除按钮逻辑
        private void btnDelete_Click(object sender, EventArgs e)
        {
            DeleteAndEnabled(true);
        }

        // 启用按钮逻辑
        private void btnEnabled_Click(object sender, EventArgs e)
        {
            DeleteAndEnabled(false);
        }

        // 删除和启用逻辑
        private void DeleteAndEnabled(bool isDelete)
        {
            if (dataGridView1.SelectedRows.Count == 0)
            {
                string msg = isDelete ? "删除" : "启用";
                MessageBox.Show($"请选择要{msg}的数据！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            dynamic models = new List<T>();
            foreach (DataGridViewRow item in dataGridView1.SelectedRows)
            {
                int id = int.Parse(item.Cells[0].Value.ToString());
                var model = SqlSugarHelper.Db.Queryable<T>().InSingle(id);
                if (isDelete)
                {
                    if (model.Status == 1) continue;
                    model.Status = 1;
                }
                else
                {
                    if (model.Status == 0) continue;
                    model.Status = 0;
                }
                model.LastUpdateUserId = LoginHelper.User.UserId;
                model.LastUpdateTime = DateTime.Now;
                models.Add(model);
            }

            if (models.Count == 0)
            {
                string msg1 = isDelete ? "禁用" : "正常";
                string msg2 = isDelete ? "删除" : "启用";
                MessageBox.Show($"您选择的数据是{msg1}的，不必{msg2}！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            int row = SqlSugarHelper.Db.Updateable(models).ExecuteCommand();
            if (row <= 0)
            {
                string msg = isDelete ? "删除" : "启用";
                MessageBox.Show($"{msg}数据失败，请联系管理员！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            btnSearch.PerformClick();
        }

        // 格式化单元格
        private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            if (e.RowIndex >= 0 && dataGridView1.Columns[e.ColumnIndex].Name == "StatusName")
            {
                if (e.Value != null && e.Value.ToString() == "禁用") e.CellStyle.ForeColor = Color.DarkRed;
            }
        }
        #endregion

        #region 子窗体必须重写的代码
        public virtual void UcPager1_PageChanged(object sender, EventArgs e) { }
        #endregion
    }
}
